#pragma once

#include "quque.h"
#include <vector>

#define THREAD_HANDLE
#define THREAD_CREATE(f)
#define THREAD_JOIN(h)

class IThreadTask {
public:
    virtual ~IThreadTask() {}
    //为什么使用void*而不使用模板？
    virtual void OnThread(void* param) = 0;
};

class ThreadPool {
    struct ThreadData {
        IThreadTask* mTask;
        void* mParam;

        ThreadData(IThreadTask* t = NULL, void* p = NULL) 
        : mTask(t)
        , mParam(p) {}
    };

public:
    ThreadPool() {
    }

    virtual ~ThreadPool() {
    }

    bool Init(int num) {
        for (int i = 0; i < num; ++i) {
            THREAD_HANDLE h = CREATE_THREAD;
            mThreads.push_back(h);
        }
    }

    void Join() {
        // 这里为什么要写成两次？
        for (std::vector<THREAD_HANDLE>::iterator it = mThreads.begin(); it != mThreads.end(); ++it) {
            mQueue.push(ThreadData());
        }
        for (std::vector<THREAD_HANDLE>::iterator it = mThreads.begin(); it != mThreads.end(); ++it) {
            THREAD_JOIN(*it);
        }
    }

    int Execute(IThreadTask * task, void* param) {
        // 告诉调用者线程池当前未处理的任务数
        return mQueue.push(ThreadData(task, param));
    }

protected:
    void OnThread() {
        ThreadData data;
        while (1) {
            if (mQueue.pop(data)) {
                if (data.mTask) {
                    data.mTask->OnThread(data.mParam);
                } else {
                    break;
                }
            }
        }
    }

protected:
    std::vector<THREAD_HANDLE> mThreads;
    queue<ThreadData> mQueue;
};
